/**
  ******************************************************************************
  * File Name          : cf.c
  * Description        : 
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "bsp.h"
#include "tskcfg.h"
#include "cf.h"

/* 除粪控制任务 */
#define CFACT_TSK_PRIORITY                        (tskIDLE_PRIORITY + 3)
#define CFACT_STACK_SIZE                          512u
TaskHandle_t xCfAct_Thd = NULL;
StaticTask_t xCfAct_Tcb;
StackType_t  xCfAct_Stk[ CFACT_STACK_SIZE ];

/* 除粪输入检测任务 */
#define CFDTC_TSK_PRIORITY                        (tskIDLE_PRIORITY + 4)
#define CFDTC_STACK_SIZE                          512u
TaskHandle_t xCfDtc_Thd = NULL;
StaticTask_t xCfDtc_Tcb;
StackType_t  xCfDtc_Stk[ CFDTC_STACK_SIZE ];

/* 除粪时间控制任务 */
#define CFTIM_TSK_PRIORITY                        (tskIDLE_PRIORITY + 5)
#define CFTIM_STACK_SIZE                          512u
TaskHandle_t xCfTim_Thd = NULL;
StaticTask_t xCfTim_Tcb;
StackType_t  xCfTim_Stk[ CFTIM_STACK_SIZE ];


/* 输入检测信号量 */
SemaphoreHandle_t Cf_InDetect_Shd = NULL;
static StaticSemaphore_t cf_indetect_area;
 
/* 485 接收消息队列 */
QueueHandle_t Cf_RxCmd_Qhd = NULL;
static StaticQueue_t cf_rxcmd_stru;
static uint8_t       cf_rxcmd_area[CF_RXCMDQUE_LENGTH * CF_RXCMDQUE_ITEMSIZE];

const uint16_t Cf_SendCmdOn  = CF_CMD_ON;
const uint16_t Cf_SendCmdOff = CF_CMD_OFF;

void vCfAct_Task( void * pvParameters )
{
	uint16_t rcmd;
	
	Cf_BspInit();
	
	Cf_RxCmd_Qhd = xQueueCreateStatic(CF_RXCMDQUE_LENGTH, \
	                                  CF_RXCMDQUE_ITEMSIZE, \
	                                  cf_rxcmd_area, \
	                                  &cf_rxcmd_stru);
  TIM6->CR1 |= TIM_CR1_CEN;
  
	while(1)
	{
		if(xQueueReceive(Cf_RxCmd_Qhd, &rcmd, 950) == pdTRUE)
		{
			switch(rcmd)
			{
				case CF_CMD_ON:   /* 点动开 */
					RELAY01(1);
					vTaskDelay(700);
					RELAY01(0);
					break;
				
				case CF_CMD_OFF:  /* 点动关 */
					RELAY02(1);
					vTaskDelay(700);
					RELAY02(0);
					break;
				
				default:
					break;
			}
		}
		
		RELAY01(0);
		RELAY02(0);
		
		vTaskDelay(50);
	}
}

void vCfDtc_Task( void * pvParameters )
{
  Cf_InDetect_Shd = xSemaphoreCreateBinaryStatic(&cf_indetect_area);
  
	while(1)
	{
		xSemaphoreTake(Cf_InDetect_Shd, 1000);
		
		if(IN01() == 0)
		{
			vTaskDelay(100);
			if(IN01() == 0)
			{
				vTaskDelay(100);
				if(IN01() == 0)
				{
					Cf_State.cfkg_st = 1;  /* 检测正转 */
          Cf_State.cfst = 1;
				}
			}
		}
		
		if(IN02() == 0)
		{
			vTaskDelay(100);
			if(IN02() == 0)
			{
				vTaskDelay(100);
				if(IN02() == 0)
				{
					Cf_State.cfkg_st = 1;  /* 检测反转 */
          Cf_State.cfst = 2;
				}
			}
		}
		
		if((IN01() != 0)  && (IN02() != 0))
		{
			vTaskDelay(100);
			if((IN01() != 0)  && (IN02() != 0))
			{
				vTaskDelay(100);
				if((IN01() != 0)  && (IN02() != 0))
				{
					Cf_State.cfkg_st = 0;  /* 检测关 */
          Cf_State.cfst = 0;
				}
			}
		}
	}
}

void vCfTim_Task( void * pvParameters )
{
	uint8_t  i;

	while(1)
	{
		if(Cf_RunPara.cftmen == 1)
		{
			for(i=0; i<6; i++)
			{
				if((Sys_Runtime.allsec >= Cf_RunPara.cftm[i]) && \
           (Sys_Runtime.allsec < (Cf_RunPara.cftm[i]+3)) && \
           (Cf_RunPara.cftm[i] != 0))
				{
					if(Cf_RxCmd_Qhd != NULL)
          {
            xQueueSend(Cf_RxCmd_Qhd, &Cf_SendCmdOn, 0);
          }
				}
			}
		}
		vTaskDelay(500);
	}
}

void Sys_RunLed(void)
{
  switch(Cf_State.cfst)
  {
    case 1:
      LED1(LED_Off);
      vTaskDelay(150);
      LED1(LED_On);
      vTaskDelay(850);
      break;
    
    case 2:
      LED1(LED_Off);
      vTaskDelay(250);
      LED1(LED_On);
      vTaskDelay(750);
      break;
    
    case 0:
    default:
      LED1(LED_On);
      vTaskDelay(150);
      LED1(LED_Off);
      vTaskDelay(850);
      break;
  }
}

void Expio_DevTaskCreat(void)
{
	xCfAct_Thd = xTaskCreateStatic(vCfAct_Task,
																 "cfxAc",
																 CFACT_STACK_SIZE,
																 (void *)1,
																 CFACT_TSK_PRIORITY,
																 xCfAct_Stk,
																 &xCfAct_Tcb);
	
	xCfDtc_Thd = xTaskCreateStatic(vCfDtc_Task,
																 "cfxDt",
																 CFDTC_STACK_SIZE,
																 (void *)1,
																 CFDTC_TSK_PRIORITY,
																 xCfDtc_Stk,
																 &xCfDtc_Tcb);
																	
	xCfTim_Thd = xTaskCreateStatic(vCfTim_Task,
                                 "cfxTi",
                                 CFTIM_STACK_SIZE,
                                 (void *)1,
                                 CFTIM_TSK_PRIORITY,
                                 xCfTim_Stk,
                                 &xCfTim_Tcb);
}
